import 'package:ddstore/dd_notifier.dart';
import 'package:flutter/cupertino.dart';

class DDFutureController<T> {
  static const _reloadAction = "_reloadAction";
  static const _updateData = '_updateData';
  T? _data;
  DDNotifier _notifier = DDNotifier();

  T? get data {
    return _data;
  }

  Future reload({DDFutureStatus reloadStartStatus = DDFutureStatus.loading}) {
    return _notifier.dispatch(_reloadAction, type: DDActionFutureType.wait, namedArguments: {
      #reloadStartStatus: reloadStartStatus,
    });
  }

  void updateData(T? data) {
    _notifier.dispatch(_updateData, positionalArguments: [data]);
  }
}

enum DDFutureStatus {
  success,
  failed,
  empty,
  loading,
}

/// 抽象builder 接口
abstract class DDBaseFutureBuilder<T> extends StatefulWidget {
  final Future<T?> Function() future;
  final Widget Function(BuildContext context, T? data) builder;
  final Widget Function(BuildContext context, T? data, Object? error)? errorBuilder;
  final Widget? emptyChild;
  final Widget? loadingChild;
  final T? initialData; // 初始数据
  final DDFutureStatus? initialStatus; // 初始状态
  final DDFutureStatus Function(T? data)? conditionCallback;
  final Function(T? data, DDFutureStatus status, int count)? resultCallback; // future 结果回调
  final DDFutureController<T>? controller;
  const DDBaseFutureBuilder({
    super.key,
    required this.future,
    required this.builder,
    this.errorBuilder,
    this.emptyChild,
    this.loadingChild,
    this.initialData,
    this.initialStatus,
    this.conditionCallback,
    this.resultCallback,
    this.controller,
  });
}

/// 常规 future组件
class DDFutureBuilder<T> extends DDBaseFutureBuilder<T> {
  final bool sliver;
  final bool animation;
  const DDFutureBuilder({
    super.key,
    required super.builder,
    required super.future,
    super.conditionCallback,
    super.controller,
    super.emptyChild,
    super.errorBuilder,
    super.initialData,
    super.initialStatus,
    super.loadingChild,
    super.resultCallback,
    this.sliver = false,
    this.animation = false,
  });

  @override
  State<DDFutureBuilder<T>> createState() => _DDFutureBuilderState<T>();
}

class _DDFutureBuilderState<T> extends State<DDFutureBuilder<T>> {
  DDFutureStatus _status = DDFutureStatus.loading;
  T? _data;
  int _loadCount = 0;
  Object? _e;

  @override
  void initState() {
    super.initState();
    _updateData(widget.initialData);
    _calculateInitialStatus();
    _addListener();
    _loadData(reloadStartStatus: _status);
  }

  @override
  void didUpdateWidget(covariant DDFutureBuilder<T> oldWidget) {
    if (oldWidget.controller != widget.controller) {
      _removeListener(oldWidget);
      _addListener();
    }
    super.didUpdateWidget(oldWidget);
  }

  @override
  void dispose() {
    _removeListener(widget);
    super.dispose();
  }

  // 计算初始状态
  void _calculateInitialStatus() {
    if (widget.initialStatus != null) {
      _status = widget.initialStatus!;
      return;
    }
    if (widget.initialData != null) {
      if (widget.conditionCallback != null) {
        _status = widget.conditionCallback!.call(widget.initialData);
      } else {
        _status = DDFutureStatus.success;
      }
    }
  }

  void _calculateStatus() {
    if (widget.conditionCallback != null) {
      _status = widget.conditionCallback!.call(_data);
      return;
    }
    if (_data == null) {
      _status = DDFutureStatus.failed;
    }
    _status = DDFutureStatus.success;
  }

  void _addListener() {
    widget.controller?._notifier
        .addListener(name: DDFutureController._reloadAction, callback: _loadData);
    widget.controller?._notifier
        .addListener(name: DDFutureController._updateData, callback: _updateData);
  }

  void _removeListener(DDFutureBuilder widget) {
    widget.controller?._notifier
        .removeListener(name: DDFutureController._reloadAction, callback: _loadData);
    widget.controller?._notifier
        .removeListener(name: DDFutureController._updateData, callback: _updateData);
  }

  void _updateData(T? data) {
    _data = data;
    widget.controller?._data = data;
  }

  Future _loadData({required DDFutureStatus reloadStartStatus}) async {
    _status = reloadStartStatus;
    try {
      final result = await widget.future.call();
      _updateData(result);
      _calculateStatus();
      _loadCount++;
      widget.resultCallback?.call(_data, _status, _loadCount);
    } catch (e) {
      _e = e;
      _updateData(null);
      _calculateStatus();
      _loadCount++;
      widget.resultCallback?.call(_data, _status, _loadCount);
    }
    if (mounted) {
      setState(() {});
    }
  }

  @override
  Widget build(BuildContext context) {
    Widget content;
    switch (_status) {
      case DDFutureStatus.loading:
        content = widget.loadingChild ?? CupertinoActivityIndicator();
        break;
      case DDFutureStatus.empty:
        content = widget.emptyChild ?? const SizedBox();
        break;
      case DDFutureStatus.failed:
        content = widget.errorBuilder?.call(context, _data, _e) ?? const SizedBox();
        break;
      case DDFutureStatus.success:
        content = widget.builder.call(context, _data);
        break;
    }
    if (widget.sliver) {
      return SliverToBoxAdapter(child: content);
    }
    return content;
  }
}

/// 简单的future组件，只有一个状态
class DDSimpleFutureBuilder<T> extends DDBaseFutureBuilder<T> {
  const DDSimpleFutureBuilder({
    super.key,
    required super.builder,
    required super.future,
    super.initialData,
    super.controller,
  });

  @override
  State<DDSimpleFutureBuilder<T>> createState() => _DDSimpleFutureBuilderState<T>();
}

class _DDSimpleFutureBuilderState<T> extends State<DDSimpleFutureBuilder<T>> {
  @override
  Widget build(BuildContext context) {
    return DDFutureBuilder<T>(
      builder: widget.builder,
      future: widget.future,
      initialData: widget.initialData,
      conditionCallback: (data) => DDFutureStatus.success,
      controller: widget.controller,
      emptyChild: widget.builder.call(context, null),
      errorBuilder: (context, data, error) => widget.builder.call(context, data),
      loadingChild: widget.builder.call(context, null),
    );
  }
}

/// 带动画切换效果的builder[ 只有2 个状态 初始状态，结果状态，可以用于骨架屏]
class DDCrossFadeFutureBuilder<T> extends DDBaseFutureBuilder<T> {
  final Widget Function(BuildContext context, T? data)? firstBuilder;
  const DDCrossFadeFutureBuilder({
    super.key,
    this.firstBuilder,
    required super.future,
    required super.builder,
    super.controller,
  });

  @override
  State<DDCrossFadeFutureBuilder<T>> createState() => _DDCrossFadeFutureBuilderState<T>();
}

class _DDCrossFadeFutureBuilderState<T> extends State<DDCrossFadeFutureBuilder<T>> {
  CrossFadeState _crossFadeState = CrossFadeState.showFirst;
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedCrossFade(
      firstChild: widget.builder.call(context, widget.initialData),
      secondChild: DDFutureBuilder<T>(
        builder: widget.builder,
        future: widget.future,
        controller: widget.controller,
        emptyChild: widget.builder.call(context, null),
        errorBuilder: (context, data, error) => widget.builder.call(context, data),
        loadingChild: widget.builder.call(context, null),
        resultCallback: (data, status, count) {
          if (mounted) {
            setState(() {
              _crossFadeState = CrossFadeState.showSecond;
            });
          }
        },
      ),
      crossFadeState: _crossFadeState,
      duration: const Duration(milliseconds: 300),
    );
  }
}

/// 带动画效果的 builder
class DDAnimatedSwitchBuilder extends StatefulWidget {
  const DDAnimatedSwitchBuilder({super.key});

  @override
  State<DDAnimatedSwitchBuilder> createState() => _DDAnimatedSwitchBuilderState();
}

class _DDAnimatedSwitchBuilderState extends State<DDAnimatedSwitchBuilder> {
  @override
  Widget build(BuildContext context) {
    return AnimatedSwitcher(
      duration: const Duration(milliseconds: 300),
    );
  }
}
